package net.jiastudy.biz.sys.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import cn.hutool.core.util.StrUtil;
import net.jiastudy.biz.datasync.DeptImporter;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;

import net.jiastudy.biz.enums.DeptType;
import net.jiastudy.biz.sys.entity.Dept;
import net.jiastudy.biz.sys.mapper.DeptMapper;
import net.jiastudy.biz.sys.service.DeptService;
import net.jiastudy.core.base.BaseService;
import net.jiastudy.core.exception.ServiceException;

@Service
@Transactional(rollbackFor = Exception.class)
public class DeptServiceImpl extends BaseService<DeptMapper, Dept> implements DeptService {

	@Override
	public Dept createDept(Dept dept) {
		if (this.checkCodeExists(dept.getCode(), null)) {
			throw new ServiceException("dept.code.exists", "部门code已经存在");
		}
		if (this.insert(dept)) {
			return dept;
		}
		return null;
	}

	@Override
	public boolean deleteDept(Long id) {
		return this.deleteById(id);
	}

	@Override
	public Dept updateDept(Dept dept) {
		if (this.checkCodeExists(dept.getCode(), dept.getId())) {
			throw new ServiceException("dept.code.exists", "部门code已经存在");
		}
		if (this.updateById(dept)) {
			return dept;
		}
		return null;
	}

	@Override
	public Dept getDept(Long id) {
		return this.selectById(id);
	}

	@Override
	public Page<Dept> pageDepts(Page<Dept> page, DeptType type, Map<String, String> conditions, Sort sort) {
		Wrapper<Dept> wrapper = new EntityWrapper<>();
		if (type != null) {
			wrapper.eq("type", type.getValue());
		}

		if (conditions.containsKey("keywords") && StrUtil.isNotEmpty(conditions.get("keywords"))) {
			String keywords = conditions.get("keywords");
			wrapper.andNew().like("name", keywords);
		}
		this.generateSort(wrapper, sort);
		return this.selectPage(page, wrapper);
	}

	@Override
	public List<Dept> findAllDepts() {
		Wrapper<Dept> wrapper = new EntityWrapper<>();
		wrapper.eq("disable", false);
		wrapper.orderBy("seq", true);
		return this.selectList(wrapper);
	}

	@Override
	public List<Dept> findEnableDepts() {
		Wrapper<Dept> wrapper = new EntityWrapper<>();
		wrapper.eq("disable", false);
		wrapper.orderBy("seq", true);
		return this.selectList(wrapper);
	}

	@Override
	public List<Dept> findEnableDepts(DeptType type) {
		Wrapper<Dept> wrapper = new EntityWrapper<>();
		wrapper.eq("disable", false);
		wrapper.eq("type", type);
		wrapper.orderBy("seq", true);
		return this.selectList(wrapper);
	}

	@Override
	public boolean disableDept(Long id) {
		Dept dept = this.selectById(id);
		dept.setDisable(true);
		this.updateById(dept);
		return true;
	}

	@Override
	public boolean enableDept(Long id) {
		Dept dept = this.selectById(id);
		dept.setDisable(false);
		this.updateById(dept);
		return true;
	}

	@Override
	public boolean checkCodeExists(String code, Long id) {
		if (null == code) {
			return false;
		}
		Dept entity = new Dept();
		entity.setCode(code);
		Dept dept = baseMapper.selectOne(entity);
		if (null == dept) {
			return false;
		}
		if (dept.getId().equals(id)) {
			return false;
		}
		return true;
	}

	@Override
	public Dept getDeptByCode(String code) {
		Dept entity = new Dept();
		entity.setCode(code);
		return baseMapper.selectOne(entity);
	}

	@Override
	public Dept getDeptByName(String name) {
		// 慎用
		name = name.trim();
		Dept entity = new Dept();
		entity.setName(name);
		return baseMapper.selectOne(entity);
	}

	@Override
	public List<Dept> findDeptsByIds(Set<Long> ids) {
		Wrapper<Dept> wrapper = new EntityWrapper<>();
		wrapper.in("id", ids);

		return this.selectList(wrapper);
	}

	@Override
	public void importDepts(List<DeptImporter> list) {
		for (DeptImporter deptImporter : list) {
			Dept codeDept = getDeptByCode(deptImporter.getCode());
			Dept nameDept = getDeptByName(deptImporter.getName());
			if (null == codeDept && null == nameDept) {
				Dept dept = new Dept();
				dept.setCode(deptImporter.getCode());
				dept.setName(deptImporter.getName());
				dept.setType(DeptType.other);
				createDept(dept);
			}
		}
	}
}
